package ll1;

import java.util.ArrayList;

/**
 * This class will create a LL(1) parse table 
 * @author Peter
 *
 */
public class LL1Table {
	private ArrayList<String> tokens;		//Top row of table
	private ArrayList<LL1Node> nonterminal;	//The rest of the rows of the table
	
	public LL1Table(ArrayList<String> tokenList){
		tokens = tokenList;
		tokens.remove("epilson");
		tokens.add("$");
		nonterminal = new ArrayList<LL1Node>();
	}
	
	public void addEntry(LL1Node node, String theToken){
		int index = tokens.indexOf(theToken); //find the row index (which is the token index number)
		LL1Node entryNode = new LL1Node(node.getName());
		entryNode.setContent(node.getContent());
		LL1Node temp;
		entryNode.setCol(theToken);
		if(index == -1){	//should not be -1
			System.out.println("ERROR TOKEN IS NOT FOUND");
		}
		
		temp = lookUp(node.getName());
		
		if(temp == null){	//the row did not exist in table
			nonterminal.add(new LL1Node(node.getName(), entryNode));
		}
		else{				//the row exists in table
			// scan for parsing errors
			for(int i = 0; i < temp.getOthers().size(); i++){
				if(temp.getOthers().get(i).getCol().equals(theToken)){
					System.out.println("ERROR: " + temp.getName() + "\n\tTOKEN: " + theToken + "\n\tRULE " + node.printRule() + "\n\tREASON: There is already an existing entry in table. There may be a parsing error.\n");
				}
			}
			temp.getOthers().add(entryNode);
		}
		
	}
	
	public LL1Node lookUp(String ruleName){
		for(int i = 0; i < nonterminal.size(); i++){
			if(nonterminal.get(i).getName().equals(ruleName)){
				return nonterminal.get(i);
			}
		}
		return null;
	}
	
	public LL1Node getRule(String ruleName, String token){
		LL1Node temp = lookUp(ruleName);
		for(LL1Node node : temp.getOthers()){
			if(node.getCol().equals(token)){
				return node;
			}
		}
		return null;
	}
	
	public ArrayList<String> getTokens(){
		return tokens;
	}
	
	public String toString(){
		String output = "LL1 Parse Table\n TRANSITION TOKENS: {";
		//print out top row
		for(String token : tokens){
			output += token + " ";
		}
		output += "}\n";
		//print out rest of the rows
		for(LL1Node node : nonterminal){
			output += node.getName() + "\t|";			//prints out the head of row
			for(LL1Node within : node.getOthers()){	//prints out the contents after head of row
				output += "TRANSITION ON '" + within.getCol() + "', RULE: " + within.toString() + "\t|";
			}
			output += "\n";
		}
		return output;
	}
}
